import type { ApplicationContext } from "@/core/application/application-context"
import * as _ from "lodash"

export class ApplicationActiveProcessor {
  private activeApplicationId?: string

  private zIndex: Map<string, number> = new Map<string, number>()

  private applicationContext: ApplicationContext

  constructor(applicationContext: ApplicationContext) {
    this.applicationContext = applicationContext
  }

  getActiveApplication() {
    if (!this.activeApplicationId) {
      return
    }
    return this.applicationContext.getApplication(this.activeApplicationId)
  }

  active(applicationId: string) {
    if (this.activeApplicationId === applicationId) {
      return
    }
    const lastActiveApplicationId = this.activeApplicationId
    //活跃当前应用
    this.activeApplicationId = applicationId
    this.zIndex.set(applicationId, this.findMaxZIndex() + 1)
    const application = this.applicationContext.getApplication(applicationId)
    application?.windowContext.activeProcessor.active()
    if (application && application.info.hook?.afterActive) {
      application.info.hook?.afterActive(application)
    }
    if (!lastActiveApplicationId) {
      return
    }
    const lastActiveApplication = this.applicationContext.getApplication(lastActiveApplicationId)
    if (lastActiveApplication) {
      if (lastActiveApplication.info.hook?.afterInactive) {
        lastActiveApplication.info.hook.afterInactive(lastActiveApplication)
      }
      lastActiveApplication.windowContext.activeProcessor.inactive()
    }
  }

  inactive() {
    this.activeApplicationId = undefined
  }

  isActive(applicationId: string) {
    return this.activeApplicationId === applicationId
  }

  getZIndex(applicationId: string) {
    return this.zIndex.get(applicationId) || 0
  }

  private findMaxZIndex() {
    return _.max([...this.zIndex.values()]) || 0
  }

  fromState(obj: any): void {
    if (!obj) {
      return
    }
    _.forEach(obj.zIndex, (key: string, value: number) => {
      this.zIndex.set(key, value)
    })
    const sorted = _.sortBy(_.toPairs(this.zIndex), ([, value]) => value)
    for (let i = 0; i < sorted.length; i++) {
      this.zIndex.set(sorted[i][0], i)
    }
    this.active(obj.activeApplicationId)
  }

  toState(): any {
    const obj: any = {}
    obj.activeApplicationId = this.activeApplicationId
    obj.zIndex = _.fromPairs(Array.from(this.zIndex.entries()))
    return obj
  }
}
